#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graphic.h"
#include "List.h"
#include "volume.h"

// Funcao que insere o grafico em uma lista passada como argumento
int insert_graphic(TipoLista *Lista){
	graphic *graphic1;	// Declara uma variavel tipo grafico
	int choice;		// Variavel para guardar a opcao de grafico
	// Ponteiros para guardar atributos do poliedro
	float *atribute1, *atribute2, *atribute3, *atribute4; 

	graphic1=malloc(sizeof(graphic));	// Instancia a variavel grafico

	// Le o tipo de poliedro
	printf("Digite o tipo de Poliedro: \n 1) Esfera;\n 2) Cubo; \n 3) Tetraedro;\n 4) Cilindro");
	printf("\n 5) Elipsoide \nSua escolha: ");
	scanf("%d",&choice);
	graphic1->type=choice;	// Guarda o tipo de poliedro na variavel

	printf("\nDigite o nome do poliedro: ");
	scanf("%s",&graphic1->name);

	printf("\nDigite a cor do poliedro: ");
	scanf("%s",&graphic1->cor);

	switch (choice){
		// ESFERA
		case 1: 
			// Le uma esfera, entrando com o valor do raio
			atribute1=malloc(sizeof(float));	// Instancia um float para o raio
			printf("Digite o raio da esfera: ");	// Le o raio
			scanf("%f",atribute1);			// Le o raio
			graphic1->atribute1=atribute1;		// Guarda o valor no grafico
			graphic1->volume=volume_esphere(*atribute1);	// Calula o volume e guarda na variavel volume;
			printf("Esfera de raio %1.4f e volume %1.4f\n",*(float*)graphic1->atribute1,graphic1->volume);	// Exibe o valor lido
		break;

	
		// CUBO	
		case 2:
			// Le um cubo, entrando com o valor da aresta
			atribute1=malloc(sizeof(float));	// Instancia um float para a aresta
			printf("Digite a aresta do cubo: ");	// Le a aresta
			scanf("%f",atribute1);			// Le a aresta
			graphic1->atribute1=atribute1;		// Guarda o valor no grafico
			graphic1->volume=volume_cube(*atribute1);	// Calcula o volume e guarda na variavel volume
			printf("Cubo de aresta %1.4f e volume %1.4f\n",*(float*)graphic1->atribute1,graphic1->volume);	// Exibe o valor lido
		break;


		// POLIEDRO		
		case 3:
			// Le um tetraedro, entrando com os lados da base e altura
			atribute1=malloc(sizeof(float));// Instancia um float para lado1
			atribute2=malloc(sizeof(float));// Instancia um float para lado2
			atribute3=malloc(sizeof(float));// Instancia um float para lado3
			atribute4=malloc(sizeof(float));// Instancia um float para altura
			printf("\nEnter com o valor dos lados do triangulo da base");
			printf(" e da altura.");
			printf("\nDigite o valor do lado 1: ");
			scanf("%f",atribute1);
			printf("\nLado 2: ");
			scanf("%f",atribute2);
			printf("\nLado 3: ");
			scanf("%f",atribute3);
			printf("\nAltura: ");
			scanf("%f",atribute4);
			graphic1->atribute1=atribute1;
			graphic1->atribute2=atribute2;
			graphic1->atribute3=atribute3;
			graphic1->atribute4=atribute4;
			graphic1->volume=volume_tetraedro(*(float*)graphic1->atribute1,
							  *(float*)graphic1->atribute2,
							  *(float*)graphic1->atribute3,
							  *(float*)graphic1->atribute4);
			 printf("Tetraedro com base de lados %1.4f,%1.4f,%1.4f,"
					"altura %1.4f  e volume %1.4f\n",
					*(float*)graphic1->atribute1,
					*(float*)graphic1->atribute2,
					*(float*)graphic1->atribute3,
					*(float*)graphic1->atribute4,
					graphic1->volume);
			break;
		

		// CILINDRO
		case 4: // se for um cilindro
			atribute1=malloc(sizeof(float)); // Instancia um float para o raio da base
			atribute2=malloc(sizeof(float)); // Instancia um float para a altura
			printf("Digite o valor do raio da base: ");
			scanf("%f",atribute1);
			printf("\nDigite o valor da altura: ");
			scanf("%f",atribute2);
			graphic1->atribute1=atribute1;
			graphic1->atribute2=atribute2;
			graphic1->volume=volume_cilindro(*(float*)atribute1, *(float*)atribute2);
			__fpurge(stdout);
			printf("\nCilindro com raio da base %1.4f, altura %1.4f e volume %1.4f.",
				  *(float*)graphic1->atribute1,
				  *(float*)graphic1->atribute2,
				  graphic1->volume);
			break;



		// ELIPSOIDE		
		case 5: // Se for um elipsoide
			// Le um elipsoide, entrando com o valor dos 3 semi-eixos
			atribute1=malloc(sizeof(float));	// Instancia um float para o 1o semi-eixo
			atribute2=malloc(sizeof(float));	// Instancia um float para o 2o semi-eixo
			atribute3=malloc(sizeof(float));	// Instancia um float para o 3o semi-eixo
			// Le os 3 semi-eixos e guarda no grafico
			printf("Digite o valor dos semi-eixos do elipsoide");
			printf("\n1o: ");
			scanf("%f",atribute1);
			printf("  2o: ");
			scanf("%f",atribute2);
			printf("  3o: ");
			scanf("%f",atribute3);
			
			graphic1->atribute1=atribute1;
			graphic1->atribute2=atribute2;
			graphic1->atribute3=atribute3;
			
			graphic1->volume=volume_elipsoide(*atribute1, *atribute2, *atribute3);	// Calcula e guarda o volume
			
			printf("Elipsoide de semi-eixos <%f, %f e %f> e volume %f.",*(float*)graphic1->atribute1,*(float*)graphic1->atribute2,*(float*)graphic1->atribute3,graphic1->volume);
		break;


		default:
			printf("\nVoce nao digitou uma opcao valida para o tipo!\n");
			break;
			
	}
	inserir(Lista, graphic1);	// Coloca o poliedro na lista
	return 0;
}


int remove_graphic_name(TipoLista *Lista,char *n){
	TipoItem *cel_aux;    // Cria um ponteiro para um TipoItem para varrer a lista
	graphic *graph_aux;   // Cria um ponteiro para o grafico que esta em cada TipoItem varrida
	int i=0;		// Variavel que verifica a posicao do elemento na lista

	// Primeiro, verifica se a lista e vazia
	if(vazia(Lista))
		printf("\nLista Vazia!\n");
	else {
		cel_aux=Lista->primeiro;        // Inicia a TipoItem auxiliar com a 1a TipoItem da lista
		while(cel_aux!=NULL){           // Enquanto nao terminar de ler a lista
			i++;				// Incrementa o valor do elemento na lista	
			graph_aux=cel_aux->dado;      // Coloca o grafico da TipoItem no grafico auxiliar
			if(strcmp(graph_aux->name,n)==0){
			removerPosicao(Lista,i);
			return 1;
		}
		cel_aux=cel_aux->proximo;     // Faz a TipoItem andar na lista
	}
}
 
  return 0;

}

int remove_graphic_seq(TipoLista *Lista, int x){
	TipoItem *cel_aux;    // Cria um ponteiro para um TipoItem para varrer a lista
	graphic *graph_aux;   // Cria um ponteiro para o grafico que esta em cada TipoItem varrida
	int i=0;              // Variavel que verifica a posicao do elemento na lista

	if(vazia(Lista))
		printf("\nLista Vazia!\n");
	else {
		cel_aux=Lista->primeiro;        // Inicia a TipoItem auxiliar com a 1a TipoItem da lista
		while(cel_aux!=NULL){           // Enquanto nao terminar de ler a lista
			i++;                          // Incrementa o valor do elemento na lista      
			graph_aux=cel_aux->dado;      // Coloca o grafico da TipoItem no grafico auxiliar
			if(i==x){
				removerPosicao(Lista,i);
				return 1;
			}
			cel_aux=cel_aux->proximo;     // Faz a TipoItem andar na lista
		}
	}
	return 0;
}

// Ordena a lista de figuras por nome
void order_graphic_name(TipoLista *Lista){
	TipoItem *cel_aux, *cel_aux2;      	// Ponteiros para varrer a lista
	graphic *graph_aux, *graph_aux2;   	// Ponteiros para guardar os dados
	TipoLista *Lista2;					//Lista ordenada
	int i=0; int j=0;				    // Variaveis que verificam a posicao do elemento na lista
	int inserido;						// Indica se o grafico foi inserido

	if(vazia(Lista))
		printf("\nLista Vazia!\n");
	else {
		Lista2 = criarLista();			// Cria a lista que estará ordenada
		cel_aux=Lista->primeiro;		// Inicia a TipoItem auxiliar com a 1a TipoItem da lista
		while(cel_aux!=NULL){			// Enquanto nao terminar de ler a lista...
			i++;							// Incrementa o indice do elemento na lista
			graph_aux=cel_aux->dado;		// Coloca o grafico da TipoItem no grafico auxiliar
			
			cel_aux2=Lista2->primeiro;		// Inicia a TipoItem auxiliar 2 com a 1a TipoItem da lista ordenada
			j=1;							// Indice no elemento na lista ordenada
			inserido = 0;					// Indica se o grafico auxiliar ja foi inserido na lista odenada
			while(!inserido){				// Enquanto nao inserir o grafico auxiliar na lista ordenada...
				if (cel_aux2==NULL){								// Se estiver no ultimo item...
					inserirPosicao(Lista2, graph_aux, j);				// Inserir
					inserido=1;											// Marcar a ainserção
				}
				else {												// Senão...
					graph_aux2=cel_aux2->dado;							// Coloca o grafico da TipoItem no grafico auxiliar
					if(strcmp(graph_aux2->name,graph_aux->name)>0){		// Se ja estiver na posicao de inserir...
						inserirPosicao(Lista2, graph_aux, j);				// Inserir
						inserido=1;											// Marcar a ainserção
					}
					cel_aux2=cel_aux2->proximo;							// Faz a TipoItem auxiliar 2 andar na lista
					j++;												// Incrementa o valor do elemento na lista      
				}
			}
			cel_aux=cel_aux->proximo;		// Faz a TipoItem auxiliar andar na lista
		}
		Lista->primeiro = Lista2->primeiro;	// Substituti a lista antiga pela lista ordenada
	}
}

// Ordena a lista de figuras por volume
void order_graphic_volume(TipoLista *Lista){
	TipoItem *cel_aux, *cel_aux2;      	// Ponteiros para varrer a lista
	graphic *graph_aux, *graph_aux2;   	// Ponteiros para guardar os dados
	TipoLista *Lista2;					//Lista ordenada
	int i=0; int j=0;				    // Variaveis que verificam a posicao do elemento na lista
	int inserido;						// Indica se o grafico foi inserido

	if(vazia(Lista))
		printf("\nLista Vazia!\n");
	else {
		Lista2 = criarLista();			// Cria a lista que estará ordenada
		cel_aux=Lista->primeiro;		// Inicia a TipoItem auxiliar com a 1a TipoItem da lista
		while(cel_aux!=NULL){			// Enquanto nao terminar de ler a lista...
			i++;							// Incrementa o indice do elemento na lista
			graph_aux=cel_aux->dado;		// Coloca o grafico da TipoItem no grafico auxiliar
			
			cel_aux2=Lista2->primeiro;		// Inicia a TipoItem auxiliar 2 com a 1a TipoItem da lista ordenada
			j=1;							// Indice no elemento na lista ordenada
			inserido = 0;					// Indica se o grafico auxiliar ja foi inserido na lista odenada
			while(!inserido){				// Enquanto nao inserir o grafico auxiliar na lista ordenada...
				if (cel_aux2==NULL){								// Se estiver no ultimo item...
					inserirPosicao(Lista2, graph_aux, j);				// Inserir
					inserido=1;											// Marcar a ainserção
				}
				else {												// Senão...
					graph_aux2=cel_aux2->dado;							// Coloca o grafico da TipoItem no grafico auxiliar
					if(graph_aux2->volume > graph_aux->volume){			// Se ja estiver na posicao de inserir...
						inserirPosicao(Lista2, graph_aux, j);				// Inserir
						inserido=1;											// Marcar a ainserção
					}
					cel_aux2=cel_aux2->proximo;							// Faz a TipoItem auxiliar 2 andar na lista
					j++;												// Incrementa o valor do elemento na lista      
				}
			}
			cel_aux=cel_aux->proximo;		// Faz a TipoItem auxiliar andar na lista
		}
		Lista->primeiro = Lista2->primeiro;	// Substituti a lista antiga pela lista ordenada
	}
}


